package com.jvxb.manage.livable.util;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class RedisCmdAnalysisUtil {
	
	public static final RedisCmdAnalysisUtil inst = new RedisCmdAnalysisUtil();
	
	private RedisCmdAnalysisUtil(){
	}
	
	public static RedisCmdAnalysisUtil getInstance() {
		return inst;
	}
	
	public List<String> analysisRedisCmd(String cmd){
    	List<String> cmdParam = new ArrayList<>();
    	String tmp = cmd;
    	int firstCharType = getFirstCharType(tmp);
    	while(true) {
    		RedisCmdVo subRedisParamByType = subRedisParamByType(firstCharType,tmp);
    		cmdParam.add(subRedisParamByType.subCmd);
    		if(StringUtils.isEmpty(subRedisParamByType.lastCmd)) {
    			break;
    		}
    		firstCharType = getFirstCharType(subRedisParamByType.lastCmd);
    		tmp = subRedisParamByType.lastCmd;
    		
    	}
    	return cmdParam;
    }
    
    private int getFirstCharType(String str) {
    	int flag = 0;
    	switch (str.substring(0, 1)) {
		case "\"":flag =1;break;
		case "'":flag=2;break;
		default:
			break;
		}
    	return flag;
    }
    
    private RedisCmdVo subRedisParamByType(int type,String cmd) {
    	RedisCmdVo tmp = null;
    	switch(type) {
    		case 0:
    			tmp = subRedisParamBySpace(cmd);
    			break;
    		case 1:
    			tmp = subRedisParamByQuo(cmd,"\"");
    			break;
    		case 2:
    			tmp = subRedisParamByQuo(cmd,"\'");
    			break;
    	}
    	return tmp;
    }
    
    private RedisCmdVo subRedisParamBySpace(String cmd) {
    	int index = cmd.trim().indexOf(" ");
    	RedisCmdVo vo = new RedisCmdVo();
    	if(index == -1) {
    		vo.setSubCmd(cmd);
    	}else {
    		vo.setSubCmd(cmd.substring(0, index));
        	vo.setLastCmd(cmd.substring(index+1).trim());
    	}
    	return vo;
    }
    
    private RedisCmdVo subRedisParamByQuo(String cmd,String chartStr) {
    	int begin = 1,end = -1;
    	int leftSlashNumb = 0; 
    	for(int i = begin ; i < cmd.length() ; i++) {
    		String tmp = cmd.substring(i, i+1);
    		if(tmp.equalsIgnoreCase(chartStr)) {
    			if(leftSlashNumb % 2 == 0) {
    				end = i+1;
    				break;
    			}
    		}if(tmp.equalsIgnoreCase("\\")) {
    			leftSlashNumb++;
    		}else{
    			leftSlashNumb = 0;
    		}
    	}
    	RedisCmdVo vo = new RedisCmdVo();
    	vo.setSubCmd(cmd.substring(begin, end-1));
    	vo.setLastCmd(cmd.substring((end+1 >= cmd.length() ? end:end+1)).trim());
    	return vo;
    }
    
    @Data
    private class RedisCmdVo{
    	private String subCmd;
    	private String lastCmd;
    }
}
